﻿#region Copyright information
// 
// Copyright © 2012-2013 Yongkee Cho. All rights reserved.
// 
// This code is a part of the SubnetworkToolkit and governed under the terms of the
// GNU Lesser General  Public License (LGPL) version 2.1 which accompanies this distribution.
// For more information on the LGPL, please visit http://bol.codeplex.com/license.
// 
// - Filename: GraphMlWriter.cs
// - Author: Yongkee Cho
// - Email: yongkeecho@outlook.com
// - Date Created: 2013-01-30 2:55 PM
// - Last Modified: 2013-01-30 3:21 PM
// 
#endregion
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Xml.Linq;

namespace SubnetworkToolkit.IO
{
    public class GraphMlWriter
    {
        private readonly FileStream _fs;
        private readonly string _name;
        private readonly IEnumerable<Gene> _genes; 
        private readonly IEnumerable<Tuple<Gene, Gene, int>> _interactions;
        private readonly IEnumerable<string> _propertyNames; 

        public GraphMlWriter(string path, string name, IEnumerable<Gene> genes, IEnumerable<Tuple<Gene, Gene, int>> interactions)
        {
            if (path == null)
                throw new ArgumentNullException("path");
            if (name == null)
                throw new ArgumentNullException("name");
            if (interactions == null)
                throw new ArgumentNullException("interactions");

            _fs = new FileStream(path, FileMode.Create);
            _name = name;
            _genes = genes;
            _interactions = interactions;
            _propertyNames = _genes.First().Property.Keys;
        }

        public bool Write()
        {
            var xmlns = XNamespace.Get("http://graphml.graphdrawing.org/xmlns");
            var xsi = XNamespace.Get("http://www.w3.org/2001/XMLSchema-instance");
            var schemaLocation = XNamespace.Get("http://graphml.graphdrawing.org/xmlns http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd");

            var xd = new XDocument(
                new XDeclaration("1.0", "utf-8", "no"),
                new XElement(xmlns + "graphml",
                    new XAttribute(XNamespace.Xmlns + "xsi", xsi),
                    new XAttribute(xsi + "schemaLocation", schemaLocation),
                        new XElement("key",
                                new XAttribute("attr.name", "Pattern"),
                                new XAttribute("attr.type", "double"),
                                new XAttribute("for", "node"),
                                new XAttribute("id", "Pattern")
                        ),
                        from propertyName in _propertyNames select
                            new XElement("key",
                                new XAttribute("attr.name", propertyName),
                                new XAttribute("attr.type", "double"),
                                new XAttribute("for", "node"),
                                new XAttribute("id", propertyName)
                            ),

                    new XElement("graph",
                        new XAttribute("edgedefault", "undirected"),
                        new XAttribute("id", _name),
                        from gene in _genes select 
                            new XElement("node",
                                new XAttribute("id", gene.Symbol),
                                from property in gene.Property select
                                    new XElement("data",
                                        new XAttribute("key", property.Key),
                                        property.Value
                                    )
                            ),
                        from ic in _interactions select
                            new XElement("edge",
                                new XAttribute("source", ic.Item1.Symbol),
                                new XAttribute("target", ic.Item2.Symbol),
                                new XElement("data",
                                    new XAttribute("key", "Pattern"),
                                    ic.Item3
                                )
                            )
                        )));

            xd.Save(_fs, SaveOptions.OmitDuplicateNamespaces);

            return true;
        }

        public void Close()
        {
            _fs.Close();
        }
    }
}
